﻿using Furion.DependencyInjection;
using Furion.FriendlyException;
using Gear.Core.ErrorControl;
using Gear.ORM.Core.DeepDB;
using Gear.Web.Api.DynamicDataApi.Model;
using Gear.Web.Api.DynamicDataApi.Macro;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Gear.ToolKits.Helper;
using Gear.Core.Entities;
using Newtonsoft.Json.Linq;
using Furion;
using Gear.Core.Result;
using Gear.Core.Entities.BizBase;
using Newtonsoft.Json;
using Gear.Web.Api.Entities.Entity;
using Gear.ORM.Core.Tenant;

namespace Gear.Web.Api.DynamicDataApi.Business
{
    public class BusinessWorker: IBusinessWorker, ITransient
    {

        /// <summary>
        /// 注入仓储
        /// </summary>
        private readonly ISqlSugarRepository _repository;
        public BusinessWorker(ISqlSugarRepository repository)
        {
            _repository = repository;
        }

        #region == 系统常量 ==

        private static readonly int FieldDelType= Convert.ToInt32(App.Configuration["FieldFilter:DelType"]); // 数据字段类型获取方式

        #endregion

        #region == 操作接口 ==
        /// <summary>
        /// 操作驱动解析
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public object _ActionSorting(HttpRequestModel model)
        {

                // 接口解析
                var _model = InterfaceImplement(model);
                object result = _model.ExecuteType switch
                {
                    // 数据获取
                    ExecuteType.MapGet => MapQuery(_model.actionid,_model.ExecuteContent, _model.Param, _model.repository),
                    // 存储过程执行（业务逻辑）
                    ExecuteType.MapProcedure => MapProcedure(_model.ExecuteContent, _model.Param, _model.repository),
                    // 数据执行（Sql执行）
                    ExecuteType.MapRun => MapRun(_model.ExecuteContent, _model.Param, _model.repository),
                    // 内置方法类
                    ExecuteType.MapClassFun => MapClassFun(_model.ExecuteContent, _model.Param),
                    // HttpApi类
                    ExecuteType.MapHttpApi => MapHttpApi(_model.ExecuteContent, _model.Param),
                    _ => throw Oops.Oh(ErrorCodeModel.E1100_3, (int)_model.ExecuteType),
                };
                return result;
            
        }
        /// <summary>
        /// 获取数据字段（仅限数据获取接口）
        /// </summary>
        public bool _ActionDataForamt(int actionid)
        {

            var execparm = _repository.Context.Ado.SqlQuery<ExecParm>("select id,controllerid, executetype,contents,isloginverft from api_action where id=@actionid", new { actionid }).SingleOrDefault();
            if (execparm == null) return false;
            var poolid= _repository.Context.Ado.SqlQuery<int>("select connectionid from api_controller where id=@id", new { id=execparm.controllerid }).SingleOrDefault();
            var repository = DBPoolImplement(poolid);
            var ColContent = $"{execparm.contents} limit 0,1";
            dynamic ColData;
            try
            {
                ColData = repository.Ado.SqlQuery<dynamic>(ColContent).ToList().FirstOrDefault();
            }
            catch
            {
                throw Oops.Oh(ErrorCodeModel.E2100_3_1);
            }
            
            
            if(ColData is ICollection<KeyValuePair<string, object>>)
            {
                List<Api_field> _ins =new ();

                static int fun(object value)
                {

                    int res = 0;

                    switch (value.GetType().Name)
                    {

                        case "Int32":
                            res = 1;
                            break;
                        case "String":
                            res = 2;
                            break;
                        case "DateTime":
                            res = 3;
                            break;
                    }

                    return res;

                }
                var sorts = _repository.Context.Ado.SqlQuery<int>(@"select ifnull(max(sorts),0) from api_field where ActionID=@ActionID", new { ActionID=actionid }).SingleOrDefault();
                foreach (KeyValuePair<string, object> kpv in ColData)
                {
                    sorts+=5;
                    _ins.Add(new Api_field
                    {
                        ActionID = actionid,
                        Sorts = sorts,
                        FieldName= kpv.Key,
                        FieldNiceName= kpv.Key.ToUpper(),
                        FieldEscapeName= kpv.Key.ToLower(),
                        FieldDataType=fun(kpv.Value),
                        IsBinding=1,
                        FieldClass=0,
                        IsDeleted=0,
                        CreatedTime=DateTime.Now,
                        UpdatedTime=DateTime.Now,
                    }); ;
                }
                try
                {
                    if(FieldDelType==0)// 不删除原有数据
                    {
                        _repository.Context.Insertable(_ins).AS("Api_field").ExecuteCommand();
                    }
                    else// 删除原有数据
                    {
                        _repository.Context.Deleteable<Api_field>().Where(x => x.ActionID == actionid && x.FieldClass == 0).ExecuteCommand();
                        _repository.Context.Insertable(_ins).AS("Api_field").ExecuteCommand();
                    }
                    

                    return true;
                }
                catch
                {
                    throw Oops.Oh(ErrorCodeModel.E2100_3);
                }
                
            }

            return false;

        }
        #endregion

        #region == 配置接口 ==

        #region == 获取 ==
        /// <summary>
        /// 获取系统配置
        /// </summary>
        /// <returns></returns>
        public async Task<List<Sys_cluster>> SystemPages() => await _repository.Context.Queryable<Sys_cluster>().Where(i=>i.IsDeleted==0).ToListAsync();

        /// <summary>
        /// 获取作用域配置
        /// </summary>
        /// <returns></returns>
        public async Task<List<Api_area>> AreaPages(int systemid)=>await _repository.Context.Queryable<Api_area>().Where(i=>i.SystemId== systemid && i.IsDeleted == 0).ToListAsync();

        /// <summary>
        /// 获取数据库配置
        /// </summary>
        /// <returns></returns>
        public async Task<List<Sys_connectionpool>> ConnectionPoolPages(int systemid) => await _repository.Context.Queryable<Sys_connectionpool>().Where(i => i.SystemId == systemid && i.IsDeleted == 0).ToListAsync();

        /// <summary>
        /// 获取控制器配置
        /// </summary>
        /// <returns></returns>
        public async Task<List<Api_controller>> ControllerPages(int areaid)=> await _repository.Context.Queryable<Api_controller>().Where(i => i.AreaID == areaid && i.IsDeleted == 0).ToListAsync();

        /// <summary>
        /// 获取方法配置
        /// </summary>
        /// <returns></returns>
        public async Task<List<Api_action>> ActionPages(int controllerid) => await _repository.Context.Queryable<Api_action>().Where(i => i.ControllerID == controllerid && i.IsDeleted == 0).ToListAsync();

        /// <summary>
        /// 获取自定义字段配置
        /// </summary>
        /// <returns></returns>
        public async Task<List<Api_field>> FieldPages(int actionid) => await _repository.Context.Queryable<Entities.Entity.Api_field>().Where(i => i.ActionID == actionid && i.IsDeleted == 0).ToListAsync();
        #endregion

        #region == 调整（新增/修改/删除） ==
        /// <summary>
        /// 编辑系统配置表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> SystemEdit(Sys_cluster dto)
        {
            int res;
            if (dto.Id>0)
            {
                dto.UpdatedTime = DateTime.Now;
                res = await _repository.Context.Updateable(dto).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
            }
            else
            {
                dto.IsDeleted = 0;
                dto.CreatedTime = DateTime.Now;
                dto.UpdatedTime = DateTime.Now;
                dto.TenantId = TenantTool.GetTenantsId();
                dto.SystemCode = Guid.NewGuid().ToString();
                res = await _repository.Context.Insertable(dto).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
            }
            return res > 0;
        }
        /// <summary>
        /// 编辑作用域配置表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> AreaEdit(Api_area dto)
        {
            int res;
            if (dto.Id > 0)
            {
                dto.UpdatedTime = DateTime.Now;
                res = await _repository.Context.Updateable(dto).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
            }
            else
            {
                dto.IsDeleted = 0;
                dto.CreatedTime = DateTime.Now;
                dto.UpdatedTime = DateTime.Now;
                dto.TenantId = TenantTool.GetTenantsId();
                res = await _repository.Context.Insertable(dto).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
            }
            return res > 0;
        }
        /// <summary>
        /// 编辑数据库连接池配置表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> ConnectionPoolEdit(Sys_connectionpool dto)
        {
            int res;
            if (dto.Id > 0)
            {
                dto.UpdatedTime = DateTime.Now;
                res = await _repository.Context.Updateable(dto).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
            }
            else
            {
                dto.IsDeleted = 0;
                dto.CreatedTime = DateTime.Now;
                dto.UpdatedTime = DateTime.Now;
                dto.TenantId = TenantTool.GetTenantsId();
                dto.ConnectionCode = Guid.NewGuid().ToString();
                res = await _repository.Context.Insertable(dto).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
            }
            return res > 0;
        }
        /// <summary>
        /// 编辑控制器配置表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> ControllerEdit(Api_controller dto)
        {
            int res;
            if (dto.Id > 0)
            {
                dto.UpdatedTime = DateTime.Now;
                res = await _repository.Context.Updateable(dto).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
            }
            else
            {
                dto.IsDeleted = 0;
                dto.CreatedTime = DateTime.Now;
                dto.UpdatedTime = DateTime.Now;
                dto.TenantId = TenantTool.GetTenantsId();
                dto.ControllerCode=Guid.NewGuid().ToString(); 
                res = await _repository.Context.Insertable(dto).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
            }
            return res > 0;
        }
        /// <summary>
        /// 编辑方法配置表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> ActionEdit(Api_action dto)
        {
            int res;
            if (dto.Id > 0)
            {
                dto.UpdatedTime = DateTime.Now;
                res = await _repository.Context.Updateable(dto).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
            }
            else
            {
                dto.IsDeleted = 0;
                dto.CreatedTime = DateTime.Now;
                dto.UpdatedTime = DateTime.Now;
                dto.TenantId = TenantTool.GetTenantsId();
                dto.ActionCode=Guid.NewGuid().ToString();
                res = await _repository.Context.Insertable(dto).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
            }
            return res > 0;
        }
        /// <summary>
        /// 编辑方法配置表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> FieldEdit(Api_field dto)
        {
            int res;
            if (dto.Id > 0)
            {
                dto.UpdatedTime = DateTime.Now;
                res = await _repository.Context.Updateable(dto).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
            }
            else
            {
                dto.IsDeleted = 0;
                dto.CreatedTime = DateTime.Now;
                dto.UpdatedTime = DateTime.Now;
                dto.TenantId = TenantTool.GetTenantsId();
                res = await _repository.Context.Insertable(dto).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
            }
            return res > 0;
        }
        #endregion

        #endregion

        #region == 执行操作 ==
        // 数据获取
        private object MapQuery(int actionid,string ExecuteContent, Dictionary<string, object> param, SqlSugarClient repository)
        {
            #region == 语句拼装阶段 ==
            // 参数正则匹配
            ExecuteContent = $"select gearres.* from ({RegexMacro.RegexTrans(ExecuteContent, param)}) gearres where 1=1";
            // 查询条件匹配
            ExecuteContent = FactorMacro.FactorTrans(ExecuteContent, param);

            var TotalContent = ExecuteContent.Replace("gearres.*", "count(1)");
            // 排序条件匹配
            ExecuteContent = SequenceMacro.SequenceTrans(ExecuteContent, param);
            // 分页条件匹配
            ExecuteContent = PageMacro.PageTrans(ExecuteContent, param);
            #endregion

            #region == 语句执行阶段 ==
            List<dynamic> data = new();
            try
            {
                if (!string.IsNullOrEmpty(ExecuteContent)) data = repository.Ado.SqlQuery<dynamic>(ExecuteContent).ToList();
            }
            catch
            {
                throw Oops.Oh(ErrorCodeModel.E2100_1, ExecuteContent);
            }
            #endregion

            #region == 结果集序列化阶段 ==
            if (data.Count > 0)
            {
                // 结果集序列化
                var _res=DatalayoutImplement(actionid, data, param, repository);

                if (_res.Count == 1) return _res.SingleOrDefault();
                if (_res.Count > 1)
                {
                    int total = repository.Ado.SqlQuery<int>(TotalContent).FirstOrDefault();
                    PagesRturn pages = PageImplement(total, param);
                    return pages ==null? new { result = _res }  : new  { result = _res, page=pages };

                }
            }
            return null;
            #endregion

        }
        // 存储过程执行（业务逻辑）
        private object MapProcedure(string ExecuteContent, Dictionary<string, object> param, SqlSugarClient repository)
        {
            // 检查过程
            PD_CheckImplement("gearadmin", ExecuteContent, repository);

            // 检查参数
            PD_CheckParamImplement("gearadmin", ExecuteContent, param, repository);

            // 获取存储过程常量 
            var constant = PD_ConstantImplement(out SugarParameter p_status, out SugarParameter p_message, out SugarParameter p_result);

            // 获取存储过程变量并装载常量
            var paramster = PD_VariableImplement(param, constant);
            try
            {
                // 执行过程
                repository.Ado.UseStoredProcedure().SqlQuery<object>(ExecuteContent, paramster);

                // 返回结果
                return new { result =new ProceduresResult { p_status = p_status.Value, p_message = p_message.Value, p_result = p_result.Value } };
            }
            catch
            {
                throw Oops.Oh(ErrorCodeModel.E2400);
            }
            
        }
        // 数据执行（Sql执行）
        private object MapRun(string ExecuteContent, Dictionary<string, object> param, SqlSugarClient repository)
        {
            try
            {
                // 执行类型解析
                var res = RunTypeImplement(ExecuteContent, param, repository);

                return new { result = res };
            }
            catch
            {
                throw Oops.Oh(ErrorCodeModel.E2100_1_2, ExecuteContent);
            }
            
        }
        // 操作内置方法类
        private object MapClassFun(string ExecuteContent, Dictionary<string, object> param)
        {
            return new object();
        }
        // 操作HttpApi类
        private object MapHttpApi(string ExecuteContent, Dictionary<string, object> param)
        {
            return new object();
        }
        #endregion

        #region == 解析操作 ==

        #region== Common ==
        // 连接池解析
        private SqlSugarClient DBPoolImplement(int poolid)
        {
            try
            {
                ConnectionPool pool = _repository.Context.Ado.SqlQuery<ConnectionPool>("select ConnectionCode ConfigId,DBType DbType,ConnectionString ConnectionString from sys_connectionpool where id=@id", new { id = poolid }).SingleOrDefault();
                if(pool==null) throw Oops.Oh(ErrorCodeModel.E2000_1, $"ID:{poolid}");

                var conn= DeepPool.DeepSugar(new List<ConnectionConfig>() {
                new ConnectionConfig
                {
                    ConnectionString = pool.ConnectionString,
                    DbType = (DbType)pool.DbType,
                    IsAutoCloseConnection = true,
                    InitKeyType = InitKeyType.SystemTable,
                    ConfigId = pool.ConfigId
                } 
                });
                if(conn.Ado.GetInt("select 1 from dual")<=0) throw Oops.Oh(ErrorCodeModel.E2000_1, $"ID:{poolid}");
                return conn;
            }
            catch
            {
                throw Oops.Oh(ErrorCodeModel.E2000_1, $"ID:{poolid}");
            }
            
        }
        // 接口解析
        private ImplementmModel InterfaceImplement(HttpRequestModel model)
        { 
            ImplementmModel _model = new ();
            int? controllerid = _repository.Context.Ado.SqlQuery<int>("select id from api_controller where ControllerCode=@ControllerCode and IsDeleted=0", new { ControllerCode = model.ControllerName }).SingleOrDefault();
            int connectionid = _repository.Context.Ado.SqlQuery<int>("select connectionid from api_controller where id=@id", new { id = controllerid }).SingleOrDefault();
            if (controllerid != null)
            {
                var execparm = _repository.Context.Ado.SqlQuery<ExecParm>("select id, executetype,contents,isloginverft from api_action where ControllerID=@ControllerID and ActionCode=@ActionCode and MethodType=@MethodType and IsDeleted=0", new { ActionCode = model.ActionName, ControllerID = controllerid, MethodType = model.MethodType }).SingleOrDefault();
                if(execparm==null) throw Oops.Oh(ErrorCodeModel.E1100_1,"");
                _model.actionid = execparm.id;
                _model.ExecuteContent = execparm.contents??null;
                _model.ExecuteType = (ExecuteType)execparm.executetype;
                _model.Param = _model.ExecuteType switch
                {
                    ExecuteType.MapGet => model.QueryParam,
                    ExecuteType.MapRun => model.BodyParam,
                    ExecuteType.MapProcedure => model.BodyParam,
                    _ => null,
                };
            }
            if (_model==null) throw Oops.Oh(ErrorCodeModel.E1100_1, "");
            _model.repository = DBPoolImplement(connectionid);
            return _model;
        }
        #endregion

        #region == MapQuery ==
        // 数据返回格式解析（通过自定义数据格式进行解析）
        private List<dynamic> DatalayoutImplement(int actionid, List<dynamic> data, Dictionary<string, object> param, SqlSugarClient repository)
        {

            if (data.Count != 0)
            {
                var format = _repository.Context.Queryable<Api_field>().Where(x => x.ActionID == actionid && x.IsDeleted == 0).ToList();
                if (format == null || format.Count == 0) return data;
                List<dynamic> _res = new();
                data.ForEach(i => {
                    Dictionary<string, object> dic = new();
                    foreach (KeyValuePair<string, object> kpv in i)
                    {
                        format.ForEach(x => {
                            try
                            {
                                if (x.FieldName == kpv.Key && x.FieldClass == 0) dic.Add(x.FieldEscapeName, FieldFormatImplement(kpv.Value, x.FieldFormat));
                            }
                            catch
                            {
                                throw Oops.Oh(ErrorCodeModel.E2300_1, kpv.Key);
                            }
                            
                        });
                    }
                    format.ForEach(x => {
                        try
                        {
                            if (x.FieldClass == 1) dic.Add(x.FieldEscapeName, FieldFormatImplement(FidldEscapeImplement(x, dic, param, repository), x.FieldFormat));
                        }
                        catch
                        {
                            throw Oops.Oh(ErrorCodeModel.E2300_1, x.FieldEscapeName);
                        }

                    });
                    _res.Add(dic);
                });

                return _res;
            }

            return null;
            
        }
        // 数据字段转义解析
        private object FidldEscapeImplement(Api_field obj, Dictionary<string, object> value, Dictionary<string, object> param, SqlSugarClient repository)
        {
            object res=null;
            switch(obj.FieldEscapeType)
            {
                case 0:// 无转换
                    res= obj.ConvertCode;
                    break;
                case 1:// 数据获取转换支持集成当前结果集参数复用（~结果集包含的字段名~）与传入参数（req("传入的参数")、req('传入的参数')）
                    res = SelectTo(ConvertRegexMacro.SelectTrans(obj.ConvertCode, value));
                    break;
                case 3:// 宏替换
                    res = ConvertRegexMacro.MacroTrans(obj.ConvertCode, obj.FieldFormat);
                    break;
            }

            // 执行sql查询
            object SelectTo(string code)
            {
                try
                {
                    code = RegexMacro.RegexTrans(code, param);
                    var resData = repository.Ado.SqlQuery<dynamic>(code).ToList();
                    if (resData.Count == 1) return resData[0];
                    if (resData.Count > 1) return resData;
                    return null;
                }
                catch
                {
                    throw Oops.Oh(ErrorCodeModel.E2100_1_1, code);
                }
                
                
            }

            // 字段类型转换（仅支持数据字段转义后的参数）*****暂不考虑此方案
            //object TypeTo(int type, object value, string name)
            //{

            //    object res = new();
            //    string typnename = string.Empty;
            //    try
            //    {
            //        switch (type)
            //        {
            //            case 1:
            //                typnename = "数字型";
            //                res = (int)value;
            //                break;
            //            case 2:
            //                typnename = "字符型";
            //                res = (string)value;
            //                break;
            //            case 3:
            //                typnename = "日期型";
            //                res = (DateTime)value;
            //                break;
            //            case 99:
            //                typnename = "对象型";
            //                res = value;
            //                break;
            //        }
            //    }
            //    catch
            //    {
            //        //throw Oops.Oh(ErrorCodeModel.E2200_1, name, typnename);
            //        return Oops.Oh(ErrorCodeModel.E2200_1, name, typnename).ErrorMessage;
            //    }
            //    return res;
            //}

            return res;
        }
        // 数据格式化解析
        private object FieldFormatImplement(object value,string code)
        {
            object res = value;
            if (string.IsNullOrEmpty(code) && value.GetType().Name!= "DateTime") return res;
            try
            {
                switch (value.GetType().Name)
                {

                    case "Int32":
                        break;
                    case "String":
                        break;
                    case "DateTime":
                        DateTime dateTime = (DateTime)res;
                        res = dateTime.ToString(code);
                        break;
                }

                return res;
            }
            catch
            {
                return res;
            }
            
        }
        // 分页解析
        private PagesRturn PageImplement(int total, Dictionary<string, object> param)
        {
            param.TryGetValue(PageMacro.Pageword, out object Value);
            if (Value == null) return null;

            var PageMod = JsonHelper.DeserializeJSON<Pages>(Value.ToString());

            if (PageMod == null) return null;

            return new PagesRturn
            {
                PageIndex = PageMod.PageIndex,
                PageSize = PageMod.PageSize,
                TotalCount = total,
                TotalPages = (int)Math.Ceiling((double)total / (PageMod.PageSize)),
                HasNextPages = PageMod.PageIndex > 1 && PageMod.PageIndex < 2,
                HasPrevPages = PageMod.PageIndex < (total % PageMod.PageSize)
            };

        }
        #endregion

        #region == MapProcedure ==
        // 存储过程Check
        private void PD_CheckImplement(string dbname,string name, SqlSugarClient repository)
        {
            if (string.IsNullOrEmpty(name)) throw Oops.Oh(ErrorCodeModel.E2400_1);
            // 获取存储过程
            if (repository.Ado.SqlQuery<int>("SELECT COUNT(1) FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA=@ROUTINE_SCHEMA AND ROUTINE_TYPE='PROCEDURE' AND ROUTINE_NAME =@ROUTINE_NAME", new { ROUTINE_SCHEMA=dbname,ROUTINE_NAME = name }).SingleOrDefault()==0)
                throw Oops.Oh(ErrorCodeModel.E2400_1);
        }
        // 存储过程参数Check
        private void PD_CheckParamImplement(string dbname, string name, Dictionary<string, object> param, SqlSugarClient repository)
        {
            if (string.IsNullOrEmpty(name)) throw Oops.Oh(ErrorCodeModel.E2400_1);
            // 获取存储过程参数
            var list = repository.Ado.SqlQuery<string>("SELECT p.PARAMETER_NAME FROM INFORMATION_SCHEMA.PARAMETERS p WHERE p.SPECIFIC_NAME=@SPECIFIC_NAME AND p.SPECIFIC_SCHEMA=@SPECIFIC_SCHEMA AND p.PARAMETER_NAME NOT IN('p_status','p_message','p_result')", new { SPECIFIC_SCHEMA = dbname, SPECIFIC_NAME = name }).ToList();
            var keys = param == null?new List<string>():param.Keys.ToList();
            // 判断非法参数
            List<string> illegal= keys.Except(list).ToList();
            if(illegal.Count>0) throw Oops.Oh(ErrorCodeModel.E2401_1,string.Join(",", illegal), name);
            // 判断缺失参数
            List<string> defect = list.Except(keys).ToList();
            if (defect.Count > 0) throw Oops.Oh(ErrorCodeModel.E2401_1, string.Join(",", defect), name);

        }
        // 存储过程常量解析
        private List<SugarParameter> PD_ConstantImplement(out SugarParameter p_status, out SugarParameter p_message, out SugarParameter p_result)
        {
            // 定义基础参数
            List<SugarParameter> paramster = new ();
            p_status = new SugarParameter("@p_status", 0, true); // 存储过程执行状态
            p_message = new SugarParameter("@p_message", string.Empty, true); // 存储过程执行消息
            p_result = new SugarParameter("@p_result", string.Empty, true); // 存储过程执行返回结果
            paramster.Add(p_status);
            paramster.Add(p_message);
            paramster.Add(p_result);

            return paramster;
        }
        // 存储过程变量解析
        private List<SugarParameter> PD_VariableImplement(Dictionary<string, object> param, List<SugarParameter> paramster)
        {
            foreach (var kpv in param)
            {
                paramster.Add(new SugarParameter($"@{kpv.Key}",kpv.Value));
            }

            return paramster;
        }
        #endregion

        #region== MapRun ==
        // 数据执行类型解析
        private int RunTypeImplement(string dbname, Dictionary<string, object> param, SqlSugarClient repository)
        {
            // 解析关键字
            if (dbname.StartsWith("insert:", StringComparison.CurrentCultureIgnoreCase)) // 新增
            {
                dbname = dbname.Replace("insert:", null);
                var objStr = param.ContainsKey("value") ? param.Where(x => x.Key == "value").Select(x => x.Value).First().ToString() : throw Oops.Oh(ErrorCodeModel.E2100_1_2_1);
                var obj = JsonConvert.DeserializeObject<Dictionary<string, object>>(objStr);
                var res = repository.Insertable(obj).AS(dbname).ExecuteCommand();
                return res;
            }
            else if (dbname.StartsWith("update:", StringComparison.CurrentCultureIgnoreCase)) // 更新（逻辑）
            {
                dbname = dbname.Replace("update:", null);
                var keyStr = param.ContainsKey("key") ? param.Where(x => x.Key == "key").Select(x => x.Value).First().ToString() : throw Oops.Oh(ErrorCodeModel.E2100_1_2_1);
                var objStr = param.ContainsKey("value") ? param.Where(x => x.Key == "value").Select(x => x.Value).First().ToString() : throw Oops.Oh(ErrorCodeModel.E2100_1_2_1);
                string[] key = keyStr.Split(",").ToArray();
                var obj = JsonConvert.DeserializeObject<Dictionary<string, object>>(objStr);
                var res = repository.Updateable(obj).AS(dbname).WhereColumns(key).ExecuteCommand();
                return res;
            }
            else if (dbname.StartsWith("delete:", StringComparison.CurrentCultureIgnoreCase)) // 删除（物理）
            {
                dbname = dbname.Replace("delete:", null);
                var keyStr = param.ContainsKey("key") ? param.Where(x => x.Key == "key").Select(x => x.Value).First().ToString() : throw Oops.Oh(ErrorCodeModel.E2100_1_2_1);
                var objStr = param.ContainsKey("value") ? param.Where(x => x.Key == "value").Select(x => x.Value).First().ToString() : throw Oops.Oh(ErrorCodeModel.E2100_1_2_1);
                string[] value = objStr.Split(",").ToArray();
                var res = repository.Deleteable<object>().AS(dbname).Where($"{keyStr} in (@value) ", new { value }).ExecuteCommand();
                return res;
            }
            else
            {
                throw Oops.Oh(ErrorCodeModel.E2100_1_2_2, dbname);
            }
        }

        #endregion

        #endregion
    }

}
